package com.fms.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fms.sys.entity.Site;
import com.fms.sys.entity.SiteCategory;
import com.fms.sys.mapper.SiteMapper;
import com.fms.sys.service.ISiteService;
import com.fms.sys.service.ISiteCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
import java.io.IOException;

/**
 * <p>
 * 站点信息Service实现类
 * </p>
 *
 * @author Jinfeng
 * @since 2024-03-23
 */
@Service
public class SiteServiceImpl extends ServiceImpl<SiteMapper, Site> implements ISiteService {

    @Autowired
    private ISiteCategoryService siteCategoryService;

    @Override
    public List<Map<String, String>> parseBookmarks(MultipartFile file, String browserType) throws IOException {
        List<Map<String, String>> bookmarks = new ArrayList<>();

        switch (browserType.toLowerCase()) {
            case "chrome":
            case "safari":
                bookmarks = parseHtmlBookmarks(file);
                break;
            case "firefox":
                bookmarks = parseJsonBookmarks(file);
                break;
            default:
                throw new IllegalArgumentException("不支持的浏览器类型");
        }

        return bookmarks;
    }

    private List<Map<String, String>> parseHtmlBookmarks(MultipartFile file) throws IOException {
        List<Map<String, String>> bookmarks = new ArrayList<>();
        Document doc = Jsoup.parse(file.getInputStream(), "UTF-8", "");
        Elements links = doc.select("a");

        for (Element link : links) {
            Map<String, String> bookmark = new HashMap<>();
            bookmark.put("title", link.text());
            bookmark.put("url", link.attr("href"));
            bookmark.put("description", link.attr("description"));
            bookmark.put("add_date", link.attr("add_date"));
            bookmarks.add(bookmark);
        }

        return bookmarks;
    }

    private List<Map<String, String>> parseJsonBookmarks(MultipartFile file) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> json = mapper.readValue(file.getInputStream(), Map.class);
        List<Map<String, String>> bookmarks = new ArrayList<>();

        // Firefox书签JSON结构解析
        if (json.containsKey("children")) {
            parseFirefoxBookmarks(json, bookmarks);
        }

        return bookmarks;
    }

    private void parseFirefoxBookmarks(Map<String, Object> node, List<Map<String, String>> bookmarks) {
        List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
        if (children != null) {
            for (Map<String, Object> child : children) {
                if ("bookmark".equals(child.get("type"))) {
                    Map<String, String> bookmark = new HashMap<>();
                    bookmark.put("title", (String) child.get("title"));
                    bookmark.put("url", (String) child.get("uri"));
                    bookmark.put("description", (String) child.get("description"));
                    bookmark.put("add_date", String.valueOf(child.get("dateAdded")));
                    bookmarks.add(bookmark);
                } else if ("folder".equals(child.get("type"))) {
                    parseFirefoxBookmarks(child, bookmarks);
                }
            }
        }
    }

    @Override
    public void categorizeBookmarks(List<Map<String, String>> bookmarks) {
        // 预定义分类规则
        Map<String, List<String>> categoryRules = new HashMap<>();
        categoryRules.put("视频网站", Arrays.asList("video", "youtube", "bilibili", "youku", "iqiyi"));
        categoryRules.put("官方文档", Arrays.asList("docs", "documentation", "api", "guide"));
        categoryRules.put("图片素材", Arrays.asList("image", "photo", "picture", "icon"));
        categoryRules.put("前端工具库", Arrays.asList("npm", "github", "codepen", "js", "css"));
        categoryRules.put("导航网站", Arrays.asList("nav", "navigation", "hao123", "hao360"));
        categoryRules.put("常用工具", Arrays.asList("tool", "utility", "convert", "format"));

        for (Map<String, String> bookmark : bookmarks) {
            String url = bookmark.get("url").toLowerCase();
            String title = bookmark.get("title").toLowerCase();

            // 根据URL和标题匹配分类
            for (Map.Entry<String, List<String>> rule : categoryRules.entrySet()) {
                for (String keyword : rule.getValue()) {
                    if (url.contains(keyword) || title.contains(keyword)) {
                        bookmark.put("category", rule.getKey());
                        break;
                    }
                }
                if (bookmark.containsKey("category")) {
                    break;
                }
            }

            // 如果没有匹配到分类，设置为"其他"
            if (!bookmark.containsKey("category")) {
                bookmark.put("category", "其他");
            }
        }
    }

    @Override
    public void saveBookmarks(List<Map<String, String>> bookmarks) {
        // 获取所有分类
        List<SiteCategory> categories = siteCategoryService.list();
        Map<String, Long> categoryMap = new HashMap<>();
        for (SiteCategory category : categories) {
            categoryMap.put(category.getCategoryName(), category.getId());
        }

        for (Map<String, String> bookmark : bookmarks) {
            Site site = new Site();
            site.setSiteName(bookmark.get("title"));
            site.setSiteUrl(bookmark.get("url"));
            site.setDescription(bookmark.get("description"));
            site.setIsRecommend(false);
            site.setSortOrder(0);

            // 设置分类ID
            String categoryName = bookmark.get("category");
            Long categoryId = categoryMap.get(categoryName);
            if (categoryId == null) {
                // 如果分类不存在，使用"其他"分类
                categoryId = categoryMap.get("其他");
                if (categoryId == null) {
                    // 如果"其他"分类也不存在，创建它
                    SiteCategory otherCategory = new SiteCategory();
                    otherCategory.setCategoryName("其他");
                    otherCategory.setCategoryIcon("folder");
                    otherCategory.setIsSystem(true);
                    otherCategory.setSortOrder(999);
                    siteCategoryService.save(otherCategory);
                    categoryId = otherCategory.getId();
                    categoryMap.put("其他", categoryId);
                }
            }
            site.setCategoryId(categoryId);

            save(site);
        }
    }
}